import { sendUnaryData, ServerUnaryCall, status, UntypedHandleCall } from '@grpc/grpc-js';

import { HealthCheckResponse, HealthCheckResponse_ServingStatus, HealthCheckRequest, HealthService, HealthServer, StudentsRequest, StudentsResponse, NoRrgRequest, NoRrgResponse } from '../models/health';
import { logger, ServiceError } from '../utils';

const ServingStatus = HealthCheckResponse_ServingStatus;
const healthStatus: Map<string, HealthCheckResponse_ServingStatus> = new Map(Object.entries({
  '': ServingStatus.SERVING,
  'helloworld.Greeter': ServingStatus.SERVING,
}));

/**
 * gRPC Health Check
 * https://github.com/grpc/grpc-node/tree/master/packages/grpc-health-check
 */
class Health implements HealthServer {
  [method: string]: UntypedHandleCall;

  // public check: handleUnaryCall<HealthCheckRequest, HealthCheckResponse> = (call, callback) => {}
  public check(call: ServerUnaryCall<HealthCheckRequest, HealthCheckResponse>, callback: sendUnaryData<HealthCheckResponse>): void {
    const { service } = call.request;
    logger.info('healthCheck', service);

    const serviceStatus = healthStatus.get(service);
    logger.info('healthChe----------------ck', service, serviceStatus, healthStatus);
    if (!serviceStatus) {
      return callback(new ServiceError(status.NOT_FOUND, 'NotFoundService'), null);
    }
    logger.info('healthCheck---------------');

    callback(null, {
      status: serviceStatus,
    });
  }

  public getStudents(call: ServerUnaryCall<StudentsRequest, StudentsResponse>, callback: sendUnaryData<StudentsResponse>): void {
    const { name } = call.request;
    logger.info('getStudents', name);


    callback(null, {
      name,
      age: 22,
      city: 'beijing'
    });
  }

  public noRrg(call: ServerUnaryCall<NoRrgRequest, NoRrgResponse>, callback: sendUnaryData<NoRrgResponse>): void {
    // const { name } = call.request;
    logger.info('getStudents', call);


    callback(null, {
      message: 'this is a no argument request'
    });
  }
}

export {
  Health,
  HealthService,
  healthStatus,
  ServingStatus,
};
